﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Data.Common.CommandTrees;
using System.Data.Metadata.Edm;
using System.Linq;

namespace Artemis.Core
{
    /// <summary>
    /// Scans the command tree for occurences of entity sets and functions.
    /// </summary>
    public sealed class FindAffectedEntitySetsVisitor : DbCommandTreeScanner
    {
        private ICollection<EntitySetBase> affectedEntitySets;
        private ICollection<EdmFunction> functionsUsed;

        /// <summary>
        /// Initializes a new instance of the FindAffectedEntitySetsVisitor class.
        /// </summary>
        /// <param name="affectedEntitySets">The affected entity sets.</param>
        /// <param name="functionsUsed">The functions used.</param>
        public FindAffectedEntitySetsVisitor(ICollection<EntitySetBase> affectedEntitySets, ICollection<EdmFunction> functionsUsed)
        {
            this.affectedEntitySets = affectedEntitySets;
            this.functionsUsed = functionsUsed;
        }

        /// <summary>
        /// Implements the visitor pattern for <see cref="T:System.Data.Common.CommandTrees.DbScanExpression"/>.
        /// </summary>
        /// <param name="expression">The <see cref="T:System.Data.Common.CommandTrees.DbScanExpression"/> that is visited.</param>
        public override void Visit(DbScanExpression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }

            base.Visit(expression);
            this.affectedEntitySets.Add(expression.Target);
        }

        /// <summary>
        /// Implements the visitor pattern for <see cref="T:System.Data.Common.CommandTrees.DbFunctionExpression"/>.
        /// </summary>
        /// <param name="expression">The <see cref="T:System.Data.Common.CommandTrees.DbFunctionExpression"/> that is visited.</param>
        public override void Visit(DbFunctionExpression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }

            base.Visit(expression);
            this.functionsUsed.Add(expression.Function);
        }
    }
}
